package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Aaa3 struct {
	Id int
	A1 string
	A2 string
	// 多对多的配置
	Bbb []Bbb3 `gorm:"many2many:aaa3_bbb3;"` // 写上关联的表名！表名！表名！
}

type Bbb3 struct {
	Id int
	B1 string
	B2 string
	// b 表 多对多 a 表，也是这样写，加上中间关联表
	Aaa []Aaa3 `gorm:"many2many:aaa3_bbb3;"` // 写上关联的表名！表名！表名！
}

type Aaa3Bbb3 struct {
	// 注意关联表的字段明明，一定要是表名加上id的属性字段，驼峰写法，数据库也是 表名_id 这样的命名
	Aaa3Id int
	Bbb3Id int
}

func main() {
	db, err := gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/db1?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	// 自动创建表  自动迁移 （把结构体和数据表进行映射）
	db.AutoMigrate(&Aaa3{})
	db.AutoMigrate(&Bbb3{})
	db.AutoMigrate(&Aaa3Bbb3{})

	// 插入测试数据，查询使用
	//db.Create(Aaa3Bbb3{1, 1})
	//db.Create(Aaa3Bbb3{1, 2})
	//db.Create(Aaa3Bbb3{2, 1})
	//db.Create(Aaa3Bbb3{2, 2})
	//db.Create(Aaa3{1, "A1", "A2", nil})
	//db.Create(Aaa3{2, "A1", "A2", nil})
	//db.Create(Bbb3{1, "B1", "B2"})
	//db.Create(Bbb3{2, "B1", "B2"})

	var a []Aaa3 // 一对多
	var b []Bbb3 // 多对一

	db.Preload("Bbb").Find(&a) // 查询多个Aaa3数据
	// 可以在这里加关联子表的查询条件的，就会查询Aaa表里id不是1的作为关联条件查询的数据了
	//db.Preload("Aaa", "id != ?", 1).Find(&b) // 查询多个Bbb3数据

	// 还可以定义预加载sql，这样写法：
	db.Preload("Aaa", func(db *gorm.DB) *gorm.DB {
		return db.Where("id != ?", 1)
	}).Find(&b) // 查询多个Bbb3数据

	fmt.Println(a)
	fmt.Println(b)

	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"a": a,
			"b": b,
		})
	})

	r.Run()

}
